#include "HandAnalyser.h"
//#include "interface.h"

HandAnalyser::HandAnalyser()
{
//	m_pHandPointList.resize(m_frameNum);
}

HandAnalyser::HandAnalyser(const HandAnalyser &h)
{
	*this = h;
}

HandAnalyser& HandAnalyser::operator =(const HandAnalyser &h)
{
	this->m_pHandPointList = h.m_pHandPointList;
	return *this;
}

int HandAnalyser::getHandDirection()
{
	int flag = 0;

	//get left gesture training data set
	for (list<const XnVHandPointContext>::iterator iterList = m_pHandPointList.begin(); 
					iterList != m_pHandPointList.end(); ++iterList)
	{
		if (iterList == --m_pHandPointList.end() && flag <= getHandPointNum() - 1)
		{
			break;
		}
		if (iterList->ptPosition.X >= (++iterList)->ptPosition.X)
		{
			--iterList;
			flag = flag + 1;
			if (flag == getHandPointNum() - 1)
			{
				return GESTURE_LEFT;
			}
		}
	}

	flag = 0;
	//get right gesture training data set
	for (list<const XnVHandPointContext>::iterator iterList = m_pHandPointList.begin(); 
					iterList != m_pHandPointList.end(); ++iterList)
	{
		if (iterList == --m_pHandPointList.end() && flag <= getHandPointNum() - 1)
		{
			break;
		}
		if (iterList->ptPosition.X <= (++iterList)->ptPosition.X)
		{
			--iterList;
			flag = flag + 1;
			if (flag == getHandPointNum() - 1)
			{
				return GESTURE_RIGHT;
			}
		}
	}

	flag = 0;
	//get UpDown gesture training data set, check if list is a sequence
	for (list<const XnVHandPointContext>::iterator iterList = m_pHandPointList.begin(); 
					iterList != m_pHandPointList.end(); ++iterList)
	{
		if (iterList == --m_pHandPointList.end() && flag <= getHandPointNum() - 1)
		{
			break;
		}
		if (iterList->ptPosition.Y >= (++iterList)->ptPosition.Y)
		{
			--iterList;
			flag = flag + 1;
			if (flag == getHandPointNum() - 1)
			{
				return GESTURE_UPDOWN;
			}
		}
	}
	return GESTURE_UNKNOWN;
}

int HandAnalyser::getHandPointNum()
{
	return m_pHandPointList.size();
}

void HandAnalyser::printHandPoint()
{
	if (getHandPointNum() == 0)
	{
		cout << "No Hand Point" << endl;
	}
	else 
	{
		for(list<const XnVHandPointContext>::iterator first = m_pHandPointList.begin(); first != m_pHandPointList.end(); ++first)
		{
			cout << "Hand Point X Coordinate : " << first->ptPosition.X 
				 << " Hand Point Y Coordinate : " << first->ptPosition.Y << endl;
		}
	}
}

int HandAnalyser::loadHandPoint(const XnVHandPointContext *php)
{
	m_pHandPointList.push_back(*php);
	return m_pHandPointList.size();
}

void HandAnalyser::releaseFirstHandPoint()
{
	list<const XnVHandPointContext>::iterator first = m_pHandPointList.begin();
	m_pHandPointList.erase(first);
}

void HandAnalyser::WritetoTestSet()
{
	ofstream fout("C:\\test.dat", ios::app);
	if (getHandPointNum() == m_frameNum)
	{
		int i = 1;
		for(list<const XnVHandPointContext>::iterator first = m_pHandPointList.begin(); first != m_pHandPointList.end(); ++first)
		{
			fout << "0 " << i << ":" << first->ptPosition.X << " " << i + 1 << ":" << first->ptPosition.Y << " ";
			i = i + 2;
		}
		fout << endl;
		fout << flush;
		fout.close();
	}
}

void HandAnalyser::WritetoTrainingSet()
{
	ofstream fout("C:\\train.dat", ios::app);
	if (getHandPointNum() == m_frameNum)
	{
		int direction = getHandDirection();
		switch(direction)
		{
		case GESTURE_LEFT:
			fout << GESTURE_LEFT << " ";
			break;
		case GESTURE_RIGHT:
			fout << GESTURE_RIGHT << " ";
			break;
		case GESTURE_UPDOWN:
			fout << GESTURE_UPDOWN << " ";
			break;
		case GESTURE_UNKNOWN:
			fout << GESTURE_UNKNOWN << " ";
			break;
		default:
			fout << GESTURE_UNKNOWN << " ";
			break;
		}

		int i = 1;
		for(list<const XnVHandPointContext>::iterator first = m_pHandPointList.begin(); first != m_pHandPointList.end(); ++first)
		{
			fout << i << ":" << first->ptPosition.X << " " << i + 1 << ":" << first->ptPosition.Y << " ";
			i = i + 2;
		}
		fout << endl;
		fout << flush;
		fout.close();
	}
}

HandAnalyser::~HandAnalyser()
{
	m_pHandPointList.~list();
}